/*
 * Copyright 2008 Jens Meiss
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.hmvc4gwt.hmvc.gwt.framework.client.registry.session;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.googlecode.hmvc4gwt.hmvc.core.component.IComponent;
import com.googlecode.hmvc4gwt.hmvc.core.event.IEvent;
import com.googlecode.hmvc4gwt.hmvc.core.event.IEventListener;
import com.googlecode.hmvc4gwt.hmvc.core.registry.artifact.IArtifact;
import com.googlecode.hmvc4gwt.hmvc.core.registry.artifact.events.in.AddArtifactViewsEvent;
import com.googlecode.hmvc4gwt.hmvc.core.registry.artifact.events.in.StartArtifactEvent;
import com.googlecode.hmvc4gwt.hmvc.core.registry.component.ComponentRegistry;
import com.googlecode.hmvc4gwt.hmvc.core.registry.event.events.in.AddEventRegistryListenerEvent;
import com.googlecode.hmvc4gwt.hmvc.core.registry.session.ISessionRegistry;
import com.googlecode.hmvc4gwt.hmvc.core.registry.session.SessionRegistry;
import com.googlecode.hmvc4gwt.hmvc.gwt.client.events.in.AddViewEvent;
import com.googlecode.hmvc4gwt.hmvc.gwt.client.events.in.RemoveViewEvent;
import com.googlecode.hmvc4gwt.hmvc.gwt.client.rootpanel.RootPanelController;
import com.googlecode.hmvc4gwt.hmvc.gwt.client.view.IViewGwt;
import com.googlecode.hmvc4gwt.hmvc.gwt.framework.client.registry.session.events.in.ShowArtifactViewsEvent;
import com.googlecode.hmvc4gwt.hmvc.gwt.framework.client.registry.session.events.in.StartListOfArtifactEvent;

/**
 * 
 * 
 * @author jens.meiss
 */
public class SessionRegistryGwt extends SessionRegistry {

	private static IComponent componentSessionRegistry;

	public static ISessionRegistry getInstance() {

		if (SessionRegistryGwt.componentSessionRegistry == null) {
			SessionRegistryGwt.componentSessionRegistry = new ComponentRegistry(
					new SessionRegistryGwt());
		}

		return (ISessionRegistry) SessionRegistryGwt.componentSessionRegistry
				.getController();
	}

	private RootPanelController rootPanelController;

	private List<IViewGwt> listActiveViews;

	private SessionRegistryGwt() {
	}

	/**
	 * @param view
	 * @see com.googlecode.hmvc4gwt.hmvc.gwt.client.rootpanel.RootPanelController#addView(com.googlecode.hmvc4gwt.hmvc.gwt.client.view.IViewGwt)
	 */
	public void addView(IViewGwt view) {
		rootPanelController.addView(view);
		listActiveViews.add(view);
	}

	/**
	 * @return the listActiveViews
	 */
	private List<IViewGwt> getListActiveViews() {
		return listActiveViews;
	}

//	/**
//	 * TODO prüfen ob die methode noch sinvoll ist
//	 */
//	private void getRemoteArtifacts() {
//		IArtifactsRemoteAsync async = IArtifactsRemote.Util.getInstance();
//
//		async.getListArtifacts(new AsyncCallback<List<String>>() {
//
//			public void onFailure(Throwable caught) {
//				Window.alert(caught.getMessage());
//			}
//
//			public void onSuccess(List<String> result) {
//				startArtifacts(result);
//			}
//
//		});
//	}

	@Override
	public void handleEvent(IEvent event) {

		if (event instanceof AddViewEvent) {
			addView(((AddViewEvent) event).getView());
		} else if (event instanceof RemoveViewEvent) {
			removeView(((RemoveViewEvent) event).getView());
		} else if (event instanceof ShowArtifactViewsEvent) {
			showArtifactViews();
		} else if (event.getClass() == StartListOfArtifactEvent.class) {
			startArtifacts(((StartListOfArtifactEvent) event)
					.getListOfArtifacs());
		}

	}

	@Override
	public void init() {

		super.init();

		setListActiveViews(new ArrayList<IViewGwt>());
		setRootPanelController(new RootPanelController());

		fireEventUp(new AddEventRegistryListenerEvent(AddViewEvent.class, this));
		fireEventUp(new AddEventRegistryListenerEvent(RemoveViewEvent.class,
				this));
		fireEventUp(new AddEventRegistryListenerEvent(
				ShowArtifactViewsEvent.class, this));
		// fireEventUp(new AddEventRegistryListenerEvent(
		// GetArtifactsRemoteEvent.class, this));
		fireEventUp(new AddEventRegistryListenerEvent(
				StartListOfArtifactEvent.class, this));

		/*
		 * load the current available Artifacts from the server
		 */
		// getRemoteArtifacts();
	}

	public void registerEventListener(
			Map<Class<? extends IEvent>, IEventListener> mapEventListener) {

	}

	/**
	 * @param view
	 * @see com.googlecode.hmvc4gwt.hmvc.gwt.client.rootpanel.RootPanelController#removeView(com.googlecode.hmvc4gwt.hmvc.gwt.client.view.IViewGwt)
	 */
	public void removeView(IViewGwt view) {
		rootPanelController.removeView(view);
		listActiveViews.remove(view);
	}

	/**
	 * @param listActiveViews
	 *            the listActiveViews to set
	 */
	private void setListActiveViews(List<IViewGwt> listActiveViews) {
		this.listActiveViews = listActiveViews;
	}

	/**
	 * @param rootPanelController
	 *            the rootPanelController to set
	 */
	private void setRootPanelController(RootPanelController rootPanelController) {
		this.rootPanelController = rootPanelController;
	}

	/**
	 * 
	 */
	private void showArtifactViews() {

		getArtifactRegistry().fireEventLocal(
				new AddArtifactViewsEvent(getListActiveViews()));

	}

	/**
	 * @param result
	 */
	private void startArtifacts(List<String> listArtifacts) {

		// TODO: IArtifact Interface liefern lassen

		

		Iterator<String> iterator = listArtifacts.iterator();
		while (iterator.hasNext()) {
			String stringClassOfArtifact = iterator.next();

			Iterator<Class<? extends IArtifact>> iteratorActiveArtifacts = getArtifactRegistry().getMapActiveArtifacts().keySet().iterator();
			
			/*
			 * ist das Artefakt schon aktiviert worden todo: bessere lösung
			 * finden :)
			 */
			boolean isActive = false;
			while (iteratorActiveArtifacts.hasNext()) {
				Class<? extends IArtifact> classOfActiveArtifact = (Class<? extends IArtifact>) iteratorActiveArtifacts
						.next();

				if (classOfActiveArtifact.getName().equals(
						stringClassOfArtifact)) {
					isActive = true;
					break;
				}
			}

			/*
			 * artefakt nur starten wenn es noch nicht aktive ist
			 */
			if (!isActive) {
				fireEventUp(new StartArtifactEvent(stringClassOfArtifact));
			}

		}

	}

	@Override
	public void terminate() {
	}

}
